package com.runa.monitor.platinterface.netservice.equipment.debao;

import com.alibaba.fastjson.JSON;
import com.runa.monitor.comm.dto.Archive;
import com.runa.monitor.comm.dto.Node;
import com.runa.monitor.platinterface.backwork.function.TaskFunction;
import com.runa.monitor.platinterface.backwork.impl.RccTaskFunction;
import com.runa.monitor.platinterface.netservice.connect.commstatus.CommStatus;
import com.runa.monitor.platinterface.netservice.equipment.NetEqu;
import com.runa.persistence.DateUtil;
import com.runa.persistence.task.RequestPendingTask;
import com.runa.persistence.task.TaskTypeEnum;
import com.runa.protocol.util.ByteUtil;
import com.runa.rccprotocol.dto.ConcentratorResponseData;
import com.runa.rccprotocol.dto.debao.*;
import com.runa.rccprotocol.dto.equdata.EquData;
import com.runa.rccprotocol.dto.param.ExtendParam;
import lombok.extern.slf4j.Slf4j;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
public class DeBao2Driver extends NetEqu<String> {


    public DeBao2Driver(String serial, Integer timeout) {
        super(serial, timeout);
    }

    private EquData.EquDataType type;

    @Override
    public void readNodeEqu(List<Node> nodeList, TaskFunction function, EquData.EquDataType type) {
        if (!online()) {
            function.doApply(CommStatus.OffLine, nodeList);
            return;
        }
        this.type = type;
        switch (type) {
            case METER:
                readHouseMeter(nodeList, function);
                break;
            default:
        }
    }

    private void readHouseMeter(List<Node> hMeters, TaskFunction function) {
        Map<String, List<Node>> nodeListMap = hMeters.stream().collect(Collectors.groupingBy(Node::getModel));
        for (String model : nodeListMap.keySet()) {
            if ("HM-25-U/200".equalsIgnoreCase(model)) {
                read200HouseMeter(nodeListMap.get(model), function);
            } else {
                read100HouseMeter(nodeListMap.get(model), function);
            }
        }
    }


    private void read100HouseMeter(List<Node> hMeters, TaskFunction function) {
        for (Node node : hMeters) {
            DeBaoRequestData requestData = new DeBaoRequestData(serial());
            requestData.readHeatMeterByIndex(node.getIndex());
            requestData.setRemain(Collections.singletonList(node));
            sendRequest(requestData, function, new RequestPendingTask(TaskTypeEnum.READ_METER, node));
        }
    }

    private void read200HouseMeter(List<Node> hMeters, TaskFunction function) {
        DeBaoInfo deBaoInfo = DeBaoInfoCache.get(serial());
        if (null == deBaoInfo || deBaoInfo.expired(1)) {
            DeBaoRequestData requestData = new DeBaoRequestData(serial());
            requestData.readTime();
            sendRequest(requestData, new RccTaskFunction.EmptyTask(function.getPriority()+1));
        }
        for (Node node : hMeters) {
            DeBaoReadRequestData requestData = new DeBaoReadRequestData(serial());
            requestData.readByTime(node.getIndex());
            requestData.setRemain(Collections.singletonList(node));
            sendRequest(requestData, function, new RequestPendingTask(TaskTypeEnum.READ_METER, node));
        }
    }

//    @Override
//    public void receive(ConcentratorResponseData responseData) {
//        log.debug("{} 德宝 receive: {} {}", serial(), type, JSON.toJSONString(responseData));
//        if (responseData instanceof DeBaoResponseData) {
//            DeBaoResponseData deBaoResponseData = (DeBaoResponseData)responseData;
//            Object data = deBaoResponseData.getData();
//            if (data instanceof DeBaoAnalysisData) {
//                DeBaoAnalysisData deBaoAnalysisData = (DeBaoAnalysisData)data;
//                switch (this.type) {
//                    case METER:
//                        deBaoResponseData.addRepData(Collections.singletonList(deBaoAnalysisData.getMeter()));
//                        concentratorResponseReceive(deBaoResponseData);
//                        return;
//                    case VALVE:
//                    case PUBLIC_UNIT:
//                        deBaoResponseData.addRepData(Collections.singletonList(deBaoAnalysisData.getValve()));
//                        concentratorResponseReceive(deBaoResponseData);
//                        return;
//                }
//            }
//        }
//    }

    @Override
    public void setNodeEquArchive(List<Archive> archives, TaskFunction function) {

    }

    @Override
    public void clearNodeEquArchive(TaskFunction function) {

    }

    @Override
    public void valveOnOffControl(List<Node> valveSerial, boolean ifLock, Integer opening, TaskFunction function) {

    }

    @Override
    public void readNodeRecord(List<Integer> indexes, TaskFunction function) {

    }

    @Override
    public void sentPublicUnitRecord(List<Node> valveSerial, Integer model, Map param, TaskFunction function) {

    }

    @Override
    public void sentPublicUnitModel(List<Node> valveSerial, boolean model, TaskFunction function) {

    }

    @Override
    public void sentExtendParam(ExtendParam param, TaskFunction function) {

    }

    @Override
    public void readPublicUnitRecord(Node valveSerial, Integer model, TaskFunction function) {

    }

    @Override
    public void readPublicUnitAndMeter(Node valveSerial, Node meterSerial, TaskFunction function) {

    }

    @Override
    public void heartbeatUpdate() {

    }

    @Override
    public boolean heartStop() {
        return false;
    }
}
